/**
 * DateUtils.java Copyright(C)2012 CITS Corporation. written by CITS Corp.
 */
package com.xiangwei.util;

import java.text.DateFormat;
import java.text.Format;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.omg.CORBA.SystemException;

/**
 * copyright CITS 2012
 * 
 * @date 2012-6-20
 * @author MaJinchang
 * @version V0.1
 * @brief
 * @since 0.1
 */
public class DateUtils {

    /**
     * 日期格式
     */
    public static String PATTEN_YMD = "yyyy-MM-dd";
    
    /**
     * 日期格式
     */
    public static String PATTEN_YMD_CN = "yyyy年MM月dd日";
    /**
     * 日期格式
     */
    public static String PATTEN_YMDHM = "yyyy-MM-dd HH:mm";
    /**
     * 日期格式
     */
    public static String PATTEN_YMTOW = "yyyy-MM";

    /**
     * 日期时间 格式
     */
    public static String PATTEN_HMS = "yyyy-MM-dd HH:mm:ss";
    
    /**
     * 年月日日期格式
     * */
    public static String PATTEN_YMDHMS = "yyyy年MM月dd日 HH:mm:ss";
    /**
     * 带毫秒日期格式
     */
    public static String PATTEN_SSS = "yyyy-MM-dd HH:mm:ss.SSS";

    /**
     * 日期格式,不带分隔符
     */
    public static String PATTEN_YMD_NO_SEPRATE = "yyyyMMdd";

    /**
     * 文件重命名专用日期格式
     */
    public static String PATTEN_FILE_RENAME = "yyyyMMddHHmmssSSS";
    public static String PATTEN_FILE_RENAMES = "yyyyMMddHHmmss";
    public static String PATTEN_FILE = "yyyyMMddHH";

    public static String PATTEN_YM = "yyyyMM";
    public static String PATTEN_Y = "yyyy";

    /**
     * 大于
     */
    public static final String COMPARE_TYPE_GT = "GT";

    /**
     * 大于等于
     */
    public static final String COMPARE_TYPE_GTE = "GTE";

    /**
     * 不等于
     */
    public static final String COMPARE_TYPE_NE = "NE";

    /**
     * 日期验证复杂正则
     */
    public static String DATE_REG = "([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})(((0[13578]|1[02])(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)(0[1-9]|[12][0-9]|30))|(02(0[1-9]|[1][0-9]|2[0-9])))";

    /**
     * 日期验证简单正则
     */
    private static String DATE_REG_SIMPLE = "^\\d{4}-\\d{2}-\\d{2}$";

    /**
     * 默认的日期间隔符
     */
    public static String DEFAULT_SEPERATOR = "-";

    /**
     * 提供日期格式化工具
     * 
     * @param pattern 日期格式
     * @return 格式化工具类
     */
    private static SimpleDateFormat getDateParser(String pattern) {
        return new SimpleDateFormat(pattern);
    }

    /**
     * 将当前时间转换成指定的格式显示
     * 
     * @param pattern 日期格式
     * @return 转换后的日期字符串
     */
    public static String dateToString(String pattern) {
        return getDateParser(pattern).format(new Date());
    }

    /**
     * 将指定日期转换成指定格式的字符串
     * 
     * @param date 日期
     * @param pattern 日期格式
     * @return 转换后的日期字符串
     */
    public static String dateToString(Date date, String pattern) {
        return getDateParser(pattern).format(date);
    }

    /**
     * 将指定格式的时间转换成Date类型
     * 
     * @param date 指定日期
     * @param pattern 格式
     * @return 转换后日期
     * @throws SystemException 转换异常时，返回系统异常
     */
    public static Date stringToDate(String date, String pattern){
        if (StringUtils.isEmpty(pattern)) {
            pattern = PATTEN_YMD;
        }
        if (StringUtils.isEmpty(date)) {
            return null;
        }
        Date result = null;
        try {
            result = getDateParser(pattern).parse(date);
        } catch (ParseException e) {
           
        }
        return result;
    }

    /**
     * 将指定格式的时间转换成其他日期格式
     * 
     * @param date 指定日期
     * @param pattern 指定格式
     * @param resultPattern 目标格式
     * @return 转换后的日期字符串
     * @throws SystemException 转换异常，抛出系统异常
     */
    public static String changeDateFormat(String date, String pattern, String resultPattern){
        String result = "";
        try {
            Date dateTmp = null;
            dateTmp = getDateParser(pattern).parse(date);
            result = getDateParser(resultPattern).format(dateTmp);
        } catch (ParseException e) {
           
        }
        return result;
    }

    /**
     * 获取前一天日期
     * 
     * @param fm 日期格式
     * @return 前一天 日期
     * @throws SystemException 转换异常，抛出系统异常
     */
    public static String stringToBeforeDate(String fm) {
        String result;
        Calendar date = Calendar.getInstance();
        date.add(Calendar.DAY_OF_MONTH, -1);
        Format format = new SimpleDateFormat(fm);
        result = format.format(date.getTime());
        return result;
    }

    /**
     * 获取当前日期前30天的日期
     * 
     * @param fm 日期格式
     * @return 当前日期前三十天的日期
     * @throws SystemException 转换异常，抛出系统异常
     */
    public static String thirtyDaysBeforeNow(String fm) {
        String result;
        Calendar date = Calendar.getInstance();
        date.add(Calendar.DAY_OF_MONTH, -30);
        Format format = new SimpleDateFormat(fm);
        result = format.format(date.getTime());
        return result;
    }

    /**
     * 获取指定日期的前30天的日期
     * 
     * @param startDate 指定日期
     * @param fm 格式
     * @return 指定日期前30天的日期
     * @throws SystemException 转换异常，抛出系统异常
     */
    @SuppressWarnings("static-access")
	public static String thirtyDaysBeforeSpecifiedDate(Date startDate, String fm){
        String result;
        Calendar date = Calendar.getInstance();
        date.setTime(startDate);
        date.add(date.DAY_OF_MONTH, -30);
        Format format = new SimpleDateFormat(fm);
        result = format.format(date.getTime());
        return result;
    }

    /**
     * 获取当天日期
     * 
     * @param fm 日期格式
     * @return 当天日期
     * @throws SystemException 转换异常，抛出系统异常
     */
    public static String stringToToday(String fm){
        String result;
        Format format = new SimpleDateFormat(fm);
        result = format.format(new Date());
        return result;
    }

    /**
     * 返回某月的第一天
     * 
     * @param year 年
     * @param month 月
     * @return 某月的第一天
     */
    public static Date getFirstDayOfMonth(String year, String month) {
        //验证空
        if (StringUtils.isEmpty(year) || StringUtils.isEmpty(month)) {
            return null;
        }
        //验证年
        if (!StringUtils.matches(year, "\\d{4}")) {
            return null;
        }
        //验证月
        int monthValue = Integer.parseInt(month);
        if (monthValue > 12 || monthValue < 1) {
            return null;
        }
        //改成  yyyy-MM-dd格式
        StringBuilder sb = new StringBuilder();
        sb.append(year);
        sb.append(DEFAULT_SEPERATOR);
        sb.append(month);
        sb.append(DEFAULT_SEPERATOR);
        sb.append("01");
        return stringToDate(sb.toString(), PATTEN_YMD);
    }

    /**
     * 返回某月的最后一天
     * 
     * @param year 年
     * @param month 月
     * @return 某月的最后一天
     */
    public static Date getLastDayOfMonth(String year, String month) {
        //验证空
        if (StringUtils.isEmpty(year) || StringUtils.isEmpty(month)) {
            return null;
        }
        //验证年
        if (!StringUtils.matches(year, "\\d{4}")) {
            return null;
        }
        //验证月
        int monthValue = Integer.parseInt(month);
        if (monthValue > 12 || monthValue < 1) {
            return null;
        }
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, Integer.parseInt(year));
        cal.set(Calendar.MONTH, monthValue - 1);
        cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
        return cal.getTime();
    }

    /**
     * 返回yyyy-mm-dd格式日期
     * 
     * @param date 传入的日期
     * @return yyyy-mm-dd格式日期
     */
    public static String formatString(String date) {

        if (StringUtils.isEmpty(date) || !checkIsActiveDate(date)) {
            return "";
        }
        if (date.length() < 10) {
            return date;
        } else {
            return date.substring(0, 10);
        }
    }

    /**
     * 返回指定格式的日期字符串
     * 
     * @param date 待转化的日期数据
     * @param dateFm 日期格式
     * @return 指定格式的日期字符串
     */
    public static String formatString(Date date, String dateFm) {
        if (StringUtils.isEmpty(dateFm)) {
            dateFm = PATTEN_YMD;
        }
        if (null == date) {
            return "";
        }
        Format fm = new SimpleDateFormat(dateFm);
        return fm.format(date);
    }

    /**
     * 获取当前日期字符串
     * 
     * @param formart 日期格式
     * @return 当前日期字符串
     */
    public static String getDateFormatStr(String formart) {
        return new SimpleDateFormat(formart).format(new java.util.Date());
    }

    /**
     * 日期加年
     * 
     * @param date 日期
     * @param spans 增加数量
     * @return 增加X年后的日期
     */
    public static Date addYear(Date date, int spans) {
        return addDate(date, Calendar.YEAR, spans);
    }

    /**
     * 日期加月
     * 
     * @param date 日期
     * @param spans 增加数量
     * @return 加月后的日期
     */
    public static Date addMonth(Date date, int spans) {
        return addDate(date, Calendar.MONTH, spans);
    }

    /**
     * 日期加天
     * 
     * @param date 日期
     * @param spans 增加数量
     * @return 加天后的日期
     */
    public static Date addDay(Date date, int spans) {
        return addDate(date, Calendar.DAY_OF_MONTH, spans);
    }

    /**
     * 日期加小时
     * 
     * @param date 日期
     * @param spans 增加数量
     * @return 加小时后的日期
     */
    public static Date addHour(Date date, int spans) {
        return addDate(date, Calendar.HOUR_OF_DAY, spans);
    }

    /**
     * 日期加分钟
     * 
     * @param date 日期
     * @param spans 增加数量
     * @return 加分钟后的日期
     */
    public static Date addMinute(Date date, int spans) {
        return addDate(date, Calendar.MINUTE, spans);
    }

    /**
     * 日期加秒
     * 
     * @param date 日期
     * @param spans 增加数量
     * @return 加秒后的日期
     */
    public static Date addSecond(Date date, int spans) {
        return addDate(date, Calendar.SECOND, spans);
    }

    /**
     * 日期加法计算
     * 
     * @param date 日期
     * @param type 增加类型
     * @param spans 增加数量
     * @return 加法计算后的日期
     */
    public static Date addDate(Date date, int type, int spans) {
        Calendar inputCalendar = Calendar.getInstance();
        inputCalendar.setTime(date);
        inputCalendar.add(type, spans);
        return inputCalendar.getTime();
    }

    /**
     * 获取当前day of month
     * 
     * @return String
     */
    public static String getCurrentDayOfMonth() {
        Calendar calendar = Calendar.getInstance();
        return String.valueOf(calendar.get(Calendar.DAY_OF_MONTH));
    }

    /**
     * 获取当前月份数字
     * 
     * @return String
     */
    public static String getCurrentMonth() {
        Calendar calendar = Calendar.getInstance();
        return String.valueOf(calendar.get(Calendar.MONTH) + 1);
    }

    /**
     * 获取当前年
     * 
     * @return String
     */
    public static String getCurrentYear() {
        Calendar calendar = Calendar.getInstance();
        return String.valueOf(calendar.get(Calendar.YEAR));
    }

    /**
     * 获取当前时间，字符串类型，格式（yyyy-mm-dd）
     * 
     * @return String
     */
    public static String getCurrentDateString() {
        return getDateFormatStr(PATTEN_YMD);
    }

    /**
     * 获取当前时间， 日期类型
     * 
     * @return java.util.Date
     */
    public static Date getCurrentDate() {
        return new Date();
    }

    /**
     * 判断是否是有效日期
     * 
     * @param date 判断日期
     * @return 是否有效日期
     */
    public static boolean checkIsActiveDate(String date) {
        //先验证基本格式是否正确
        if (!StringUtils.matches(date, DATE_REG_SIMPLE)) {
            return false;
        }
        //验证复杂格式是否正确
        if (StringUtils.isNotEmpty(date) && date.contains(DEFAULT_SEPERATOR)) {
            String dateNoSeprator = date.replaceAll(DEFAULT_SEPERATOR, "");
            return StringUtils.matches(dateNoSeprator, DATE_REG);
        }
        return false;
    }

    /**
     * 日期比较， 后面日期比前面的日期大
     * 
     * @param dateFrom 开始日期
     * @param dateEnd 结束日期
     * @return boolean 比较结果
     */
    public static boolean checkDateFromTo(String dateFrom, String dateEnd) {
        if (checkDateCompare(dateFrom, dateEnd, DateUtils.COMPARE_TYPE_GTE)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 判断前后日期对比。 如果后面的日期大于前面的日期， 返回true。 否则返回false。
     * 
     * @param dateFromStr 开始日期
     * @param dateEndStr 结束日期
     * @return boolean 比较结果
     */
    private static boolean checkDateCompare(String dateFromStr, String dateEndStr, String compareType) {
        if (!checkIsActiveDate(dateFromStr) || !checkIsActiveDate(dateEndStr)) {
            return false;
        } else {
            Date dateFrom = DateUtils.stringToDate(dateFromStr, DateUtils.PATTEN_YMD);
            Date dateEnd = DateUtils.stringToDate(dateEndStr, DateUtils.PATTEN_YMD);

            if (COMPARE_TYPE_GT.equals(compareType)) {
                //大于
                if (dateFrom.before(dateEnd)) {
                    return true;
                }
            } else if (COMPARE_TYPE_GTE.equals(compareType)) {
                //大于等于
                if (!dateEnd.before(dateFrom)) {
                    return true;
                }
            } else if (COMPARE_TYPE_GTE.equals(compareType)) {
                //不等于
                if (!StringUtils.isEqual(dateFromStr, dateEndStr)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 比较两个日期大小
     * 
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 开始日期早于结束日期，返回true。否则返回false。相等，返回false
     */
    public static boolean dateCompare(Date startDate, Date endDate) {
        if (startDate.before(endDate)) {
            return true;
        }
        return false;
    }
    /**
     * 返回指定日期的年
     * 
     * @param date 指定的日期
     * @return 指定日期的年
     */
    public static String getYearFromDate(String date) {
        if (!checkIsActiveDate(date)) {
            return "";
        }
        //日期格式化
        try {
            Date dateTmp = getDateParser(PATTEN_YMD).parse(date);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(dateTmp);
            return String.valueOf(calendar.get(Calendar.YEAR));
        } catch (ParseException e) {
            return "";
        }
    }

    /**
     * 返回指定日期的月
     * 
     * @param date 指定的日期
     * @return 指定日期的月
     */
    public static String getMonthFromDate(String date) {
        if (!checkIsActiveDate(date)) {
            return "";
        }
        //日期格式化
        try {
            Date dateTmp = getDateParser(PATTEN_YMD).parse(date);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(dateTmp);
            return String.valueOf(calendar.get(Calendar.MONTH) + 1);
        } catch (ParseException e) {
            return "";
        }
    }

    /**
     * 返回指定日期的日
     * 
     * @param date 指定日期
     * @return 指定日期的日
     */
    public static String getDayFromDate(String date) {
        if (!checkIsActiveDate(date)) {
            return "";
        }
        //日期格式化
        try {
            Date dateTmp = getDateParser(PATTEN_YMD).parse(date);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(dateTmp);
            return String.valueOf(calendar.get(Calendar.DAY_OF_MONTH));
        } catch (ParseException e) {
            return "";
        }
    }
    
    /**
	 * 格式化当前日期：yyyy-MM-dd HH:mm:ss
	 * @return Date
	 */
	public static Date getNowdate(){
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date date = null;
		try {
			 date = format.parse(format.format(new Date()));
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return date;
	}
	/**
	 * 格式化当前日期yyyy年MM月dd日 HH:mm:ss
	 * */
	public static String getDate(){
		SimpleDateFormat formatter = new SimpleDateFormat(PATTEN_YMDHMS);
		String string = formatter.format(new Date());
		return string;
	}
	
	public static String getNowTime(){
		SimpleDateFormat formatter = new SimpleDateFormat(PATTEN_YMDHMS);
		String string = formatter.format(new Date());
		return string;
	}
	
	public static String getStringFullDate(){
		SimpleDateFormat formatter = new SimpleDateFormat(PATTEN_FILE_RENAMES);
		String string = formatter.format(new Date());
		return string;
	}
	
	/**
	 * 判断圣诞节活动时间
	 * */
	public static boolean compare_date(Date date){
		boolean b = false;
		try {
			DateFormat df = new SimpleDateFormat("yyyy-MM-dd hh");
			String d1 = "2015-12-21 08";
			Date date2 = df.parse(d1);
			String d2 = "2015-12-31 23";
			Date date3 = df.parse(d2);
			if(date.getTime()>=date2.getTime() && date.getTime()<=date3.getTime()){
				b = true;
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return b;
	}
	
	/**
	 * 获得两个日期直接的差值
	 * @return
	 * @throws ParseException 
	 */
	public static int getDiffDay(Date startDate, Date endDate){
		SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");  
		try {
			if(startDate != null){
				startDate=sdf.parse(sdf.format(startDate));
			}else{
				startDate = sdf.parse(sdf.format(0));
			}
			if(endDate != null){
				endDate=sdf.parse(sdf.format(endDate));  
			}else{
				endDate = sdf.parse(sdf.format(0));
			}
		} catch (ParseException e) {
			e.printStackTrace();
		}  
        Calendar cal = Calendar.getInstance();    
        cal.setTime(startDate);    
        long time1 = cal.getTimeInMillis();                 
        cal.setTime(endDate);    
        long time2 = cal.getTimeInMillis();         
        long between_days=(time2-time1)/(1000*3600*24);  
       return Integer.parseInt(String.valueOf(between_days)); 
	}
	
	
	public Map<String, Object> dateRulsSet(Map<String, Object> map){
		Date startDate = null;//开始时间
		Date endDate = null;//结束时间
		int betweenDate = 0;//相差天数
		int rulsDay = 1;//横轴显示的单位
		int size = 1;//数组长度
		if(map.get("startDate") != null){
			startDate = (Date) map.get("startDate");
		}
		if(map.get("endDate") != null){
			endDate = (Date) map.get("endDate");
		}
		if(startDate != null && endDate !=null){
			betweenDate = DateUtils.getDiffDay(startDate, endDate) + 1;
		}
		//横轴显示的规则:如果时间段小于7天则以1天为单位，如果小于15天则以2天为单位...
		if(betweenDate > 7 && betweenDate < 15){
			rulsDay = 2;
		}else if(betweenDate >=15 && betweenDate < 30){
			rulsDay = 4;
		}else if(betweenDate >=30 && betweenDate < 60){
			rulsDay = 7;
		}
		if(betweenDate != 0){
			size = (int) Math.ceil((double)betweenDate/rulsDay);
		}
		//返回参数的设定
		Map<String, Object> returnMap = new HashMap<String, Object>();
		returnMap.put("startDate",startDate);
		returnMap.put("rulsDay",rulsDay);
		returnMap.put("size",size);
		return returnMap;
	}
}
